<?php


class Macys_Base_HttpClient extends Zend_Service_Abstract {

	/**
	 * Setup the response type and gives the user about options of output
	 * @var string
	 */
	private $responseType = 'json';
	private $log;
	private $sessionInfo;

	private $curlEnabled = TRUE;
	/**
	 * Is a consturctor
	 * TODO Not sure what are commmon functionality
	 * @param unknown_type $uri
	 * @param unknown_type $config
	 */
	public function __construct($uri = null, $config = null) {
		$this->log = Zend_Registry::get('log');
		$this->sessionInfo = new Macys_Base_Session();
	}


	/**
	 * Setup the x-macys-webservice-client-id Header
	 * this will be users MAPI most of the time
	 * @param string $header_value
	 */
	public function setClientHeader($header_value) {
		$this->setHeaders(Macys_Constants::MACYS_CLIENT_HEADER, $header_value);
	}


	public function setCustomerHeader($header_value) {
		$this->setHeaders(Macys_Constants::MACYS_CUSTOMER_HEADER, $header_value);
	}

	/**
	 * Retrives the access_token from Session and addes to header for next call
	 * @param Boolean $flag
	 */
	public function isProtectedService($flag = TRUE) {
		if(isset($flag)) {
			// TODO Make the Strings to pick from GLOBAL Context
			$token = "";
			$auth = Zend_Auth::getInstance();
			if ($auth->hasIdentity()) {
				$token = $auth->getIdentity();
				$this->setUserAccessHeader($token);
			}
			else {
				$this->log->crit('SECURE DATA info not Available');
				//throw new Macys_Base_Exception('Access Token Not Available to Make Protected Call', '1000');
			}
			$x = new Macys_Oauth_Oauth();
			$client_id = $this->sessionInfo->sessionData(Macys_Constants::SESSION, 'client_id');
			if($client_id)
			$this->setClientHeader($client_id);
			else
			{
				$this->log->crit('Client Id is NOT in Session');
			}
		}
	}


	/**
	 * There are currently two ways to call Protecte service
	 * Might be one is depricated
	 * TODO Verify with Dev team which is current valid
	 * @param unknown_type $accessToken
	 */
	public function setUserAccessHeader($accessToken) {
		if(isset($accessToken)) {
			$this->getHttpClient()->setHeaders('Authorization', 'Bearer ' . $accessToken );
		}
	}

	/**
	 * Sets the UserContext for subsequent Calls
	 * Some times may require to remove this using resetHttpClient
	 * @param unknown_type $userContext
	 */
	public function setUserContextHeader($userContext = null) {
		if (isset($userContext))
		$this->getHttpClient()->setHeaders('X-Mashery-Oauth-User-Context', $userContext);
	}


	/**
	 * As Mashery Services require Basic Authentication with there client_id & secret
	 * @param string $client_id
	 * @param string $client_secret
	 */
	public function setMasheryAuth($client_id, $client_secret) {
		$this->getHttpClient()->setAuth($client_id, $client_secret);
	}

	/**
	 * To set JSON Content Type
	 * as this is used by default we will be calling in constructor
	 */
	public function setContentTypeJson() {
		$this->setContentType('application/json');
	}

	/**
	 * For Post Values in form-urlencoded
	 * @param string $type
	 */
	public function setContentType($type = 'application/x-www-form-urlencoded') {
		$this->getHttpClient()->setEncType($type);
	}

	/**
	 * Enables Curl Support for Mashery Calls
	 * We are not able to pass Authorization header with direct calls
	 * @param Boolean $flag
	 */
	public function setCurlSupport($flag = FALSE) {
		if($flag == TRUE) {
			$curlConfig = array(
    				'adapter'   => 'Zend_Http_Client_Adapter_Curl',
    				'curloptions' => array(CURLOPT_FOLLOWLOCATION => true,
			    	CURLOPT_MAXREDIRS => 3,
                	CURLOPT_SSL_VERIFYPEER => false,
					//CURLOPT_CAINFO => "C:/webserver/ProdBcom-Cert.crt"
									),
					'useragent' => 'Macys_Http_Client',
			);
			$prox = Macys_Base_Config::getInstance();
			$proxyconf = $prox->getProxy();
			if($proxyconf){
				$pr = $proxyconf;
				$curlConfig = array(
    				'adapter'   => 'Zend_Http_Client_Adapter_Curl',
    				'curloptions' => array(CURLOPT_FOLLOWLOCATION => true,
				CURLOPT_MAXREDIRS => 3,
                	CURLOPT_SSL_VERIFYPEER => false,
                	//CURLOPT_CAINFO => "C:/webserver/ProdBcom-Cert.crt"
				),
					'useragent' => 'Macys_Http_Client',	
					'proxy_user' => $pr['username'],
					'proxy_pass' => $pr['password'],
					'proxy_port' => $pr['port'],
					'proxy_host' => $pr['host']
				);
			}
			$this->log->debug('Curl configuration settings are : ' . http_build_query($curlConfig, '', ';'));
			$this->getHttpClient()->setConfig($curlConfig);
		}
		else {
			$this->curlEnabled = TRUE;
			$this->log->debug('Curl Support Enabled and will be done Just before processing Request Method');
		}
	}


	/**
	 * Accept type is Set to JSON by Default for every request
	 * If needs to Change make call with new value
	 * @param string $default
	 */
	public function setAcceptType($default = 'application/json') {
		$this->setHeaders('Accept', $default);
		if ($default == 'application/json')
		$this->responseType = 'json';
		else
		$this->responseType = 'xml';
		$this->log->debug('Setting Response Type : ' . $this->responseType);
	}


	/**
	 * Get the response as PHP ARRAY or OBJECT
	 */
	public function getResponseBodyArray($decodeType = Zend_Json::TYPE_ARRAY) {
		if ($this->responseType == 'json') {
			return Zend_Json::decode($this->getResponseBodyJson(),$decodeType);
		}
		throw new Macys_Base_Exception('HTTP Client responseType is not set', 1000);
	}

	/**
	 * Get the response as JSON
	 */
	public function getResponseBodyJson() {

		if ($this->responseType == 'json') {
			return $this->getResponseBodyCustom();
		}
		elseif($this->responseType == 'xml') {
			return Zend_Json::fromXml($this->getResponseBodyCustom(), true);
		}
		throw new Macys_Base_Exception('HTTP Client responseType is not set', 1000);
	}

	/**
	 * Get the response as XML
	 */
	public function getResponseBodyXml() {
		if ($this->responseType == 'xml') {
			return $this->getResponseBodyCustom();
		}
		throw new Macys_Base_Exception('HTTP Client responseType (Accept) parameter should be set to xml to get XML', 1000);
	}

	/**
	 * Function to log all the REQUEST & RESPONSE of HTTP client
	 * Used by QA Team to Verify the request
	 */
	private function getResponseBodyCustom() {
		try {
			$responseAll = $this->getLastResponse();
			$this->log->info('HTTP Full Response : ' . $responseAll);
			$requestAll = $this->getLastRequest();
			$this->log->info('HTTP Full Request : ' . $requestAll);
			$responseBody = $this->_getResponseBodyCustom($responseAll);
			$this->log->info('HTTP Response Body : ' . $responseBody);
		}
		catch (Exception $e) {
			$this->log->crit("Exception occured while processing details in getResponseBodyCustom()");
			$this->log->crit("Exception Details : " . $e->getMessage());
		}
		return $responseBody;
	}

	private function _getResponseBodyCustom($res) {
		try {
			if(isset($res)){
				$b = $res->getBody();
				return $b;
			}
			else {
				return null;
			}
		}
		catch (Exception $e) {
			$this->log->crit("Unable to retrive Response Body");
		}
		return null;
	}

	/**
	 * Fall back all methods to Magic Methods
	 * This is a Hack to make Singleton HTTP Client access
	 * @param string $method
	 * @param array $args
	 */
	public function __call($method, $args) {
		try {
			if($method == 'request') {
				if($this->curlEnabled == TRUE)
				$this->setCurlSupport(TRUE);
			}
			$this->log->debug('Calling Method : ' . $method  . ':: with Params = ' . http_build_query($args, '', ';'));
			return call_user_func_array(array($this->getHttpClient(), $method), $args);
		} catch (Exception $e) {
			$this->log->crit('Exception in Http Method Called : ' . $method);
			$this->log->crit('Exception Details : ' . $e->getMessage() . " Trace is : " . $e->getTraceAsString());
			// TODO
		}

	}



}